package com.hancher.gamelife2.backup;

import static com.hancher.gamelife2.backup.BaiduNetManager.BAIDU_API_UPLOAD_MESSAGE_FINISHED;

import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import androidx.navigation.Navigation;

import com.hancher.common.androidutil.AsyncUtils;
import com.hancher.common.androidutil.LogUtil;
import com.hancher.common.androidutil.MmkvUtil;
import com.hancher.common.androidutil.PathUtil;
import com.hancher.common.androidutil.ToastUtil;
import com.hancher.common.base.BaseMvpFragment;
import com.hancher.common.javautil.EmptyUtil;
import com.hancher.common.javautil.FileUtil;
import com.hancher.common.javautil.ZipUtil;
import com.hancher.gamelife2.R;
import com.hancher.gamelife2.databinding.FragmentBackupBinding;
import com.hancher.gamelife2.home.HomePresenter;
import com.hancher.gamelife2.login.BaiduLoginFragment;
import com.hancher.gamelife2.main.MainDatabase;
import com.hancher.gamelife2.main.MainDatabase_Impl;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.lxj.xpopup.XPopup;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;

/**
 * 作者 : Hancher ytu_shaoweijie@163.com <br/>
 * 时间 : 2023/3/12 0012 22:49 <br/>
 * 描述 :
 */
public class BackupSqliteFragment extends BaseMvpFragment<FragmentBackupBinding, HomePresenter> {

    private Disposable d;

    @Override
    protected void initView(Bundle savedInstanceState) {

    }

    @Override
    protected void initListener() {
        LiveEventBus.get(BaiduNetManager.BAIDU_API_UPLOAD_MESSAGE, String.class)
                .observe(this, s -> {
                    binding.tvUpload.setText("上传：" + s);

                    if (BAIDU_API_UPLOAD_MESSAGE_FINISHED.equals(s)) {
                        binding.tvOk.setVisibility(View.VISIBLE);
                        binding.tvCancel.setVisibility(View.GONE);
                        binding.imgBackuping.clearAnimation();
                        LogUtil.i("上传成功，备份结束");
                    }
                });
        LiveEventBus.get(BaiduNetManager.BAIDU_API_DOWNLOAD_MESSAGE, String.class)
                .observe(this, s -> {
                    binding.tvDownload.setText("下载：" + s);

                    if ("下载完成".equals(s)) {
                        mergeData();
                    } else if (EmptyUtil.isNotEmpty(s) && s.startsWith("下载失败")) {
                        copyInnerDb();
                    }
                });
        binding.tvOk.setOnClickListener(v -> Navigation.findNavController(binding.container).popBackStack());
        binding.tvCancel.setOnClickListener(v -> {
            if (d != null && !d.isDisposed()) {
                d.dispose();
            }
            Navigation.findNavController(binding.container).popBackStack();
        });
    }

    @Override
    protected void initData() {

    }

    @Override
    public void onResume() {
        super.onResume();
        LogUtil.d("开始检查百度登录情况");
        long expireTime = MmkvUtil.getLong(BaiduLoginFragment.BAIDUNET_EXPIRATION_TIME, 0L);
        if (System.currentTimeMillis() > expireTime) {
            new XPopup.Builder(getContext()).asConfirm("数据备份到百度网盘", "本人太穷，没有前购买服务器，因此利用百度网盘备份数据，点击确定进行登录百度网盘账号，谢谢理解。",
                            () -> Navigation.findNavController(binding.container).navigate(R.id.action_backupFragment_to_baiduLoginFragment))
                    .show();
            return;
        }

        LogUtil.d("开始申请权限");
        XXPermissions.with(this)
                .permission(Permission.WRITE_EXTERNAL_STORAGE,
                        Permission.READ_MEDIA_IMAGES,
                        Permission.READ_MEDIA_VIDEO,
                        Permission.READ_MEDIA_AUDIO)
                .request((permissions, allGranted) -> {
                    if (allGranted) {
                        downFromBaidu();
                    } else {
                        ToastUtil.show("权限未全部同意！");
                    }
                });
    }


    //region 同步数据
    //表
    final List<String> tables = Arrays.asList("matter", "function", "diary", "position", "weather", "birthday", "account", "colockin", "colockintype", "menstrual");
    //备份路径
    String path = PathUtil.OUT_APP_CACHE + File.separator + "backup" + File.separator;
    /**
     * 外部数据库
     */
    String extDbPath = PathUtil.OUT_APP_CACHE + File.separator + "backup" + File.separator + MainDatabase.DATABASE_NAME;
    //压缩包路径
    String zipPath = PathUtil.OUT_APP_CACHE + File.separator + "GameLife2Backup.zip";
    String dbPath = PathUtil.IN_DB + File.separator + MainDatabase.DATABASE_NAME;
    String destBaiduPath = BaiduNetApi.BDPAN_BACKUP_PATH + "GameLife2Backup.zip";
    //密码
    final String psd = "Hancher";
    public static final String BASE64_START = "[[BASE64]]";


    /**
     * 下载压缩包
     * 从 destBaiduPath 下载到 zipPath
     */
    private void downFromBaidu() {
        if (binding.tvOk.getVisibility() == View.GONE) {
            return;
        }
        LogUtil.d("开始下载已备份压缩包");
        binding.tvOk.setVisibility(View.GONE);
        binding.tvCancel.setVisibility(View.VISIBLE);
        // 动画旋转
        Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.rotate_animation);
        animation.setRepeatMode(Animation.INFINITE);
        animation.setRepeatCount(Animation.INFINITE);
        binding.imgBackuping.startAnimation(animation);

        d = AsyncUtils.run(emitter -> {
            FileUtil.deleteFile(zipPath);
            FileUtil.touchDir(path);
            BaiduNetManager.getInstance().downloadFile(destBaiduPath, zipPath);
        }, (Consumer<String>) data -> {

        });
    }

    /**
     * 合并数据
     * 因为分隔符问题、插件问题，因此放弃csv方案
     * 采用sqlite方案备份数据库
     * 从 dbPath 复制到 extDbPath
     */
    private void mergeData() {
        LogUtil.d("开始合并数据库");
        AsyncUtils.run(emitter -> {
            LiveEventBus.get(BaiduNetManager.BAIDU_API_DOWNLOAD_MESSAGE, String.class)
                    .post("开始解压");
            LogUtil.d("解压文件：" + zipPath);
            LogUtil.d("解压位置：" + PathUtil.OUT_APP_CACHE);
            if (new File(zipPath).exists()) {
                ZipUtil.unZip(zipPath, PathUtil.OUT_APP_CACHE, psd);

                LiveEventBus.get(BaiduNetManager.BAIDU_API_DOWNLOAD_MESSAGE, String.class)
                        .post("解压完成，开始合并");

                if (new File(extDbPath).exists()) {

                    MainDatabase_Impl.getInstance().close();

                    // dbPath 应用数据库地址; path 解压目录
                    boolean result = DBUtil.restoreDb(dbPath, extDbPath);
                    LogUtil.d("合并结果：" + result);
                    if (!result) {
                        LiveEventBus.get(BaiduNetManager.BAIDU_API_DOWNLOAD_MESSAGE, String.class)
                                .post("合并数据库失败");
                        return;
                    }

                    MainDatabase_Impl.restart();

                }
            }

            emitter.onNext("");
        }, (Consumer<String>) data -> {
            copyInnerDb();
        }, t -> {
            LiveEventBus.get(BaiduNetManager.BAIDU_API_DOWNLOAD_MESSAGE, String.class)
                    .post("解压或合并失败" + t);
            copyInnerDb();
        });
    }

    /**
     * 克隆本地数据库
     */
    private void copyInnerDb() {
        LogUtil.d("开始克隆本地数据库");
        d = AsyncUtils.run(emitter -> {
            LogUtil.d("生成路径：" + path);
            FileUtil.deleteFloder(path);
            FileUtil.touchDir(path);
            FileUtil.copyFile2Dir(new File(dbPath), new File(path));
            emitter.onNext("");
            emitter.onComplete();
        }, (Consumer<String>) data -> {
            LogUtil.d("生成csv完成");
            zipFile();
        });
    }

    /**
     * 压缩zip
     * 压缩 path 路径为 zipPath
     */
    private void zipFile() {
        LogUtil.d("开始压缩本地数据");
        AsyncUtils.run(emitter -> {
            FileUtil.deleteFile(zipPath);
            LogUtil.d("压缩开始");
            ZipUtil.zipFileUnderDir2File(path, zipPath, psd);
            FileUtil.deleteFloder(path);
            emitter.onNext("");
            emitter.onComplete();
        }, (Consumer<String>) data -> {
            LogUtil.d("压缩完成");
            uploadBaidu();
        });
    }

    /**
     * 上传百度网盘
     */
    private void uploadBaidu() {
        LogUtil.d("开始上传压缩文件");
        BaiduNetManager.getInstance().setDeleteCache(true);
        BaiduNetManager.getInstance().uploadFile(zipPath, destBaiduPath);
    }
    //endregion

//    @Override
//    public void onPause() {
//        binding.imgBackuping.clearAnimation();
//        super.onPause();
//    }
}